Skip to content

Add Rust E2E tests for SOCKS5 + HTTP CONNECT basic auth#41

Merged
madeye merged 3 commits into
feature/rust-tun2socksfrom
test/proxy-basic-auth-e2e
May 11, 2026
Merged

Add Rust E2E tests for SOCKS5 + HTTP CONNECT basic auth#41
madeye merged 3 commits into
feature/rust-tun2socksfrom
test/proxy-basic-auth-e2e

Conversation

@madeye
Copy link
Copy Markdown
Owner

@madeye madeye commented May 11, 2026

The real upstream-auth code lives in the Rust tun2socks crate (socks5_handshake, http_connect in app/src/main/rust/proxydroid-tun2socks/src/tun2socks.rs). This PR adds #[tokio::test] coverage that spins up loopback TCP listeners impersonating auth-requiring SOCKS5 and HTTP CONNECT upstreams, then drives the crate's own handshake functions against them.

Test cases

SOCKS5 (socks5_handshake)

  • ✅ correct user/pass → success
  • ✅ wrong password → SOCKS5 auth rejected
  • ✅ no creds vs auth-required upstream (server advertises 0xFF) → method not accepted

HTTP CONNECT (http_connect)

  • ✅ correct user/pass → 200
  • ✅ wrong creds → 407
  • ✅ no creds → 407

All exercise real TCP loopback against real handshakes — no mocking of the protocol code.

Drive-by cleanup

  • Deleted LocalProxyServer.kt and LocalHttpProxyTest.kt — dead since the VPN-first rewrite (ProxyDroidVpnService routes directly through Tun2SocksHelper; nothing in main/ referenced LocalProxyServer).
  • Fixed the stale comment in ProxyDroidVpnService.kt that still mentioned LocalProxyServer.
  • cargo fmt incidentally normalized two pre-existing style nits in socks4_handshake.

Tests are IP-target only

The Rust netstack uses fake-IP NAT for DNS, so in the real data path the Target passed into the handshakes is always Target::Ip(...). All six tests reflect that. The Target::Domain branches in the handshakes are not exercised here — happy to add if you want defensive coverage in case fake-IP is ever bypassed.

Verification

  • cargo fmt --all -- --check
  • cargo clippy --all-targets -- -D warnings
  • cargo test --lib → 6 passed

🤖 Generated with Claude Code

madeye and others added 3 commits May 11, 2026 17:56
The real upstream-auth code lives in the Rust tun2socks crate
(socks5_handshake, http_connect). Add #[tokio::test] coverage that
spins up loopback TCP listeners impersonating auth-requiring SOCKS5
and HTTP CONNECT upstreams, then drives the crate's own handshake
functions against them. Six cases:

  SOCKS5: correct creds, wrong creds, no creds vs auth-required.
  HTTP CONNECT: correct creds, wrong creds, no creds.

Also drop the dead Kotlin LocalProxyServer + its unit tests --
ProxyDroidVpnService no longer routes through it; tun2socks talks
to the upstream directly. Fix the stale comment that still
referenced LocalProxyServer.

cargo fmt incidentally normalized two pre-existing style nits in
socks4_handshake.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The existing HostSocks5ProxyIntegrationTest only covered NO_AUTH, and no
emulator-side HTTP CONNECT test existed at all. Extend the rig so the
instrumented suite runs both protocols across {no-auth, auth-ok,
auth-wrong-creds}:

  scripts/socks5_test_server.py:
    - Add --auth user:pass for RFC 1929 user/password sub-negotiation.

  app/src/androidTest/.../HostSocks5ProxyIntegrationTest.kt:
    - Existing NO_AUTH test unchanged.
    - New auth happy-path test against a user/password upstream.
    - New negative test asserting wrong creds get a non-zero RFC 1929
      status from the proxy.

  app/src/androidTest/.../HostHttpConnectProxyIntegrationTest.kt (new):
    - CONNECT through auth-less proxy returns 200.
    - CONNECT through auth-required proxy with correct creds returns 200.
    - Wrong creds and missing creds both return 407.

  scripts/run_emulator_tests.sh:
    Was a smoke script that never ran connectedAndroidTest. Rewrite to
    spin up all four fake upstream proxies on the host (SOCKS5 + HTTP
    CONNECT, each in no-auth and user/pass variants on ports
    1080/1081/8081/8082), wait for them to bind, then invoke
    connectedDebugAndroidTest with the matching instrumentation args.

Verified locally: ./gradlew :app:compileDebugAndroidTestKotlin succeeds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PRs into feature/** branches and pushes to test/** branches were
previously silent. Extend the workflow triggers so this PR (and
similar follow-ups) actually run CI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@madeye madeye merged commit 3e1458f into feature/rust-tun2socks May 11, 2026
8 checks passed
@madeye madeye deleted the test/proxy-basic-auth-e2e branch May 11, 2026 10:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant